package net.tribal.comic.services

import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH

import net.tribal.comic.entities.Comic
import net.tribal.comic.entities.Rate


class ComicService {

    boolean transactional = true
	def fileService
	def pageService
	def commentService
	
	
	/**
	 * 
	 * 
	 * @param segment
	 * @param offset
	 * @param ord
	 * @param sor
	 * @param admin
	 * @param custom
	 * @return
	 */
	def getActiveComics(segment, offset, ord, sor, admin, custom) {
		ord = (ord)?  ord: "dateCreated"
		sor = (sor)?  sor: "desc"
		
		def result = [:]
		def c = Comic.createCriteria()
		def results = c.list {
			if(!admin) { eq("disabled", false) }
			if(custom) { ilike("title", "%"+custom+"%") }
			
			if(offset)
				firstResult(offset)
				
			maxResults(segment)
			
			
			order(ord, sor)
		}
		
		c = Comic.createCriteria()
		def total = c.count{
			if(!admin) { eq("disabled", false) }
			if(custom) { ilike("title", "%"+custom+"%") }
		}
		
		result["data"] = results
		result["count"] = total
		return result
	}
		

    /**
     * 
     * @param segment
     * @param offset
     * @param ord
     * @param sor
     * @param admin
     * @param commentToId
     * @return
     */
    def getComicComments ( segment, offset, ord, sor, admin, commentToId ) {
    	//	Si no tenen valor, s'asigna valor per omisi�
		def result = ['data':[], 'count':0]
		def comic = Comic.createCriteria().get{
			if(!admin) { eq("disabled", false) }
			idEq(commentToId.toLong())
		}
		
		if(comic){
			result["data"] = comic.comments.sort{it.dateCreated}.reverse()
			result["count"] = comic.comments?.size()
		}
		
		return result
    }
    
	def add( instance, file ){
		
		if ( !instance.hasErrors() ) {
			//	Afegim el nou fitxer
			instance = this.changeFile( instance, file )
		}
		
		if ( !instance.save() || instance.hasErrors() ) {
			fileService.removeFile( "/comic/", instance.nameFile )
		}
		
		return instance
	}
	
	
	/**
	 * 
	 * @param instance
	 * @return
	 */
	def delete( instance ) {
		try {
			if(instance.nameFile) {
				if( !(fileService.removeFile( "/comic/", instance.nameFile )) ) {
					instance.errors.rejectValue('',null,'no se ha podido borrar el fichero')
					log.debug "No se ha podido borrar la imagen con el nombre: ${instance.nameFile} y parametros: ${instance.toString()}"
					return instance
				}
			}
			

			instance.page?.each() {
				pageService.delete(it)
			}

			def fans = instance.fans
			def comments = [:]
			
			fans.each{user->
				log.debug "trying to remove userComments from ${user}"
				user.userComments = []
			}
			
			
			fans.each{user->
				log.debug "trying to remove ${user}"
				instance.removeFromFans(user)
			}
			
			
			instance.delete()
			return instance
		}
		catch (org.springframework.dao.DataIntegrityViolationException e) {
			instance.errors.rejectValue('',null,'no se ha podido borrar el fichero por motivos de integridad de datos')
			log.debug "No se ha podido borrar la imagen con el nombre: ${instance.nameFile} y parametros: ${instance.toString()}"
			return instance
		}
	}
	
	
	/**
	 * 
	 * @param instance
	 * @return
	 */
	def changeProfile( instance ) {
		
		if (!instance){
			instance.errors.rejectValue("", "comic.update.fault")
			return instance
		}
		
		if (instance.version) {
			def version = instance.version.toLong()
			if (instance.version > version) {
				instance.errors.rejectValue("version", "comic.optimistic.locking.failure")
				return instance
			}
		}
		
		
		if ( !instance.hasErrors() ) {
			instance.save()
		}
		
		return instance
	}
	
	
	/**
	 * 
	 * @param instance
	 * @param file
	 * @return
	 */
	def changeFile( instance, file ) {
		
		//	Si existeix un fitxer amb aquest nom el borrem
		if( instance.id && file != null && !file.isEmpty() && instance.nameFile != null ) {
			def nameList = instance.nameFile.tokenize(".")
			if( !(fileService.removeFile( "/comic/", instance.nameFile ) && fileService.removeFile( "/comic/", nameList[0] + "_thumbnail." + nameList[1])) ) { 
				instance.errors.rejectValue('pathFile', delete.error, null, "NO SE HA PODIDO ELIMINAR EL FICHERO")
				return instance
			}
		}
		
		if ( file != null && !file.isEmpty() ) {
			
			def validate = fileService.validate(file, CH.config.comics.maxSizeComic)
			if(validate.ext != null) {
				def randomName = fileService.addFile(file, "/comic/", validate.ext)
				
				if (randomName == null) {		//	No ha podido guardar el fichero
					instance.errors.rejectValue('pathFile', 'file.not.save')
				}
				
				instance.nameFile = randomName + "." + validate.ext
				
			} else {
				instance.errors.rejectValue('pathFile', validate.error, null, "ERROR VALIDACION")
			}
		} else {
			instance.nameFile = null 
		}
		
		return instance
	}
	
	
	def getRateOldRate ( comic, userSession ) {
		def oldRateId = Comic.createCriteria().get{
			ratings{
				eq("createdBy", userSession)
				
				projections {
					groupProperty("rate")
				}
			}
			idEq(comic.ident().toLong())
		}
		
		if(oldRateId){
			return oldRateId  
		}
		
		return 0
	}
	
	def getIdOldRate ( comic, userSession ) {
		def oldRateId = Comic.createCriteria().get{
			ratings{
				eq("createdBy", userSession)
				
				projections {
					groupProperty("id")
				}
			}
			idEq(comic.ident().toLong())
		}
		
		if(oldRateId){
			return oldRateId  
		}
		
		return null
	}
	
	/**
     * Puntua una p�gina alternativa.
     * Si el usuari que puntua, ja ha puntuat, s'actualitza el seu vot,
     * si no, afegeix un vot nou.
     * 
     * @param rate 			- puntuaci�
     * @param comic			- comic que ser� puntuat
     * @param userSession	- usuari autenticat
     * @return
     * 	- true : ok
     *  - false: ko
     */
	def rate ( rate, comic, userSession ) {
		try{
			def oldRateId = this.getIdOldRate( comic, userSession )
			
			if(oldRateId){
				// L'usuari ja ha votat anteriorment
				def oldRate = Rate.get(oldRateId)
				oldRate.rate = rate.toFloat()
				comic.save()
			}else{
				// Es el primer vot de l'usuari
				def newRate = new Rate()
				newRate.rate = rate.toFloat()
				newRate.createdBy = userSession
				
				comic.addToRatings(newRate)
				comic.save()
			}
			return true
    	}catch (Exception e) {
			println e
    		return false
		}
    }
}